<?php
namespace app\index\controller;

use app\common\controller\PayBase;
use think\Db;
use app\index\model\ChongzhiList;
use think\Exception;

class Paykf extends PayBase
{
    protected $pay_memberid;
    protected $key;
    protected $pay_url;
    protected $pay_notifyurl;
    protected $pay_callbackurl;
    protected $ctime;

    public function __construct()
    {
        parent::__construct();
        $this->pay_memberid = '10011'; //商户ID
        $this->key = 'e8gg29gbpwxlg0ftus2z9rx4ebmopfq9'; //密钥
        $this->pay_url = 'http://api.597kf.com/Pay_Index.html'; //支付提交地址
        $this->pay_notifyurl = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'] . '/index/Paykf/callBank'; //服务端返回地址
        $this->pay_callbackurl = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'] . '/index/Paykf/hrefUrl'; //页面跳转返回地址
        $this->ctime = time();
    }

    /**
     * 快付支付调起接口
     */
    public function initPay($username='',$pay_type='',$amount=-1,$from=0)
    {
        //接收数据
        $user = cookie('username','');
        $password = cookie('password','');
        $username =  empty($username) ? input('post.username','') : $username;
        $pay_type = empty($pay_type) ? input('post.pay_type','') : $pay_type;
        $amount = -1==$amount ? input('post.amount',0) : $amount;

        if ($pay_type == 'null' || $pay_type == '') return packJson('', '请选择支付方式', 500);
        $pay_method = Db::name('pay_type_list')
            ->alias("a")
            ->join('__PAY_METHOD__ b','a.method_id=b.id','LEFT')
            ->where(['a.method'=>5,'a.type_value'=>$pay_type])
            ->field('a.type_name,b.name,b.id,b.method,b.money')->find();
        $remark = $pay_method['type_name'].'-'.$pay_method['name'];
        //若为网银支付支付则转换银行编码
        $bank_code = '';
        if (!is_numeric($pay_type)) {
            $bank_code = $pay_type;
            $pay_type = '907';
        }
        //验证用户信息
        if( 0==$from ){
            if(!$user || !$username || ($user!=$username)) return packJson('','用户身份验证失败',500);
            $user_info = Db::name('username')->field('id,us_class,swzh,nbzh')->where(['username'=>$username,'password'=>$password])->find();
        }else{
            $user_info = Db::name('username')->field('id,us_class,swzh,nbzh')->where(['username'=>$username])->find();
        }
        if (!$user_info) return packJson('', '用户身份验证失败', 500);
        if ($user_info['swzh'] == 1) return packJson('', '试玩账号无法充值', 500);
        if ($user_info['nbzh'] == 1) return packJson('', '内部账号不支持线上充值', 500);

        //充值防骚扰是否开启，并进行处理
        $harassment = Db::name('xt_czfsr')->find();
        if ($harassment['open'] > 0) {
            $nowys = $this->ctime - $harassment['time_xs'] * 60;
            $old_czjl = Db::name('chongzhi_list')->where('username', $username)->where('cztime', '>', $nowys)->find();
            if ($old_czjl['id'] > 0) {
                return packJson('', "系统充值防骚扰已开启，{$harassment['time_xs']}分钟内只能充值1次！", 500);
            }
        }

        //验证金额
        if ($amount <= 0) return packJson('', '请输入充值金额', 500);
        if ($amount < 10) return packJson('', '最低充值金额为十元人民币', 500);
        if ($amount > 5000) return packJson('', '充值金额超过范围', 500);

        //计算优惠金额
        $msje = $msbs = 0;
        $cz_set = Db::name('xt_chongzhi')->find();
        $user_class = Db::name('us_class')->where('id', $user_info['us_class'])->find();
        $zsje = $amount * $user_class['czzsbl'] / 100;
        $zsbs = $user_class['czzsbl'];
        if ($amount >= $cz_set['xscz_je']) {
            $msje = $amount * $cz_set['xscz_zs'] / 100;
            $msbs = $cz_set['xscz_zs'];
        }
        //充值方案赠送
        $method_money = 0.00;
        if( floatval( $pay_method['money'] ) > 0 ){
            if( 0==intval( $pay_method['method'] ) ){
                //金额
                $method_money = $pay_method['money'];
            }else{
                //比例
                $method_money = floatval($amount) * floatval($pay_method['money']) / 100;
            }
        }
        $method_money = sprintf("%.2f",substr(sprintf("%.3f", $method_money), 0, -2));

        //生成订单号
        $order_sn = 'KFF' . str_pad($user_info['id'], 5, '0', STR_PAD_LEFT) . rand(1111, 9999);
        //组装数据
        if( 1==$from ) $this->pay_callbackurl.="Third";
        $data = array(
            'pay_memberid' => $this->pay_memberid,
            'pay_orderid' => $order_sn,
            'pay_amount' => $amount,
            'pay_applydate' => date('Y-m-d H:i:s', $this->ctime),
            'pay_bankcode' => $pay_type,
            'pay_notifyurl' => $this->pay_notifyurl,
            'pay_callbackurl' => $this->pay_callbackurl
        );
        ksort($data);

        $data['pay_md5sign'] = $this->bulidSign($data);
        $data['pay_attach'] = '';
        $data['pay_productname'] = '充值服务';
        if ($pay_type == '907') $data['pay_bank'] = $bank_code;
        $ret = $this->curl_post_https($this->pay_url, $data);
        if( empty($ret) ){
            return packJson('', "接口信息错误", 500);
        }else{
            $ret = json_decode($ret,true);
            if( 'error'==trim($ret['status']) ){
                return packJson('', $ret['msg'], 500);
            }else{
                /**@todo*/
            	$u = Db::name('username')->where('username',$username)->value('je');
                $model = new ChongzhiList();
                if( $model->setTransRechargeInfo($order_sn, $amount, $username, 0, 0, 1, $remark, $this->ctime, '快付线上支付', '系统自动', get_ip(), 0, $pay_type, $zsje, $zsbs, $msje, $msbs, $user_info['us_class'],'',0,$method_money,$u) ){
                    //跳转支付页
                    return packJson($ret['data']['url'], '', 200);
                }else{
                    return packJson('',"订单生产错误",500);
                }
            }
        }
    }

    /**
     * 回调接口
     */
    public function callBank()
    {
        Db::startTrans();
        $memberid = input('post.memberid', '');
        $orderid = input('post.orderid', '');
        $amount = input('post.amount', '');
        $datetime = input('post.datetime', '');
        $transaction_id = input('post.transaction_id', '');
        $returncode = input('post.returncode', '');
        $sign = input('post.sign', '');
        $ctime = time();

        $return = array(
            'memberid' => $memberid,
            'orderid' => $orderid,
            'amount' => $amount,
            'datetime' => $datetime,
            'transaction_id' => $transaction_id,
            'returncode' => $returncode
        );
        ksort($return);
        reset($return);

        $key = $this->key;
        $md5str = $this->bulidSign($return);
        $sign_str = strtoupper(md5($md5str . 'key=' . $key));

        if ($sign_str == $sign && $returncode == '00') {
            //更新用户金额、打码量等相关信息
            $order_info = Db::name('chongzhi_list')->where('ddbh', $orderid)->find();
            if ($order_info['je'] != $amount) return 'error';
            $user_info = Db::name('username')->where('username', $order_info['username'])->find();
            $dml_set = Db::name('xt_dmsz')->where('id', 1)->find();
            $xtcz = Db::name('xt_chongzhi')->where('id', 1)->find();
            if ($xtcz['dmopen'] == 1) {
                $dmls = ($order_info['hy_msje'] + $order_info['hy_zsje'] + $order_info['je']+ $order_info['method_money']) * $dml_set['xscz_dmbs'];
            } else {
                $dmls = $order_info['je'] * $dml_set['xscz_dmbs'];
            }
            //充值后账户总金额
            $czhje = $order_info['hy_msje'] + $order_info['hy_zsje'] + $order_info['je'] + $user_info['je']+ $order_info['method_money'];
            //充值总金额
            $czzje = $order_info['je'] + $user_info['czzje'];
            //用户当前打码量
            $dml = $user_info['dml'] + $dmls;
            try {
                $zt = model('ChongzhiList')->where(['ddbh'=>$orderid])->value('zt');
                if( 1==intval($zt) ){
                    throw new Exception("该订单已经成功通知");
                }
                if( !model('ChongzhiList')->updateRechargeInfo($orderid, $transaction_id, 1, $czhje, $ctime) ){
                    throw new Exception("更新订单信息错误");
                }
                if( !model('Username')->upUserXsczInfo($czhje, $dml, $czzje, $order_info['username']) ){
                    throw new Exception("更新用户金额错误");
                }
                Db::name('username')->where('username',$order_info['username'])->setInc('cz_num');
                $fav_money = $order_info['hy_msje'] + $order_info['hy_zsje']+ $order_info['method_money'];

                //满送金额，等级赠送金额，充值方案赠送金额
                $extcj = array(
                    'username'=>$user_info['username'],
                    'user_class'=>$user_info['us_class'],
                    'fstime'=>time(),
                    'czadmin' => '系统赠送',
                );
                $cjhje = floatval($order_info['je']) + floatval($user_info['je']) + floatval($order_info['hy_msje']);
                if( floatval($order_info['hy_msje']) > 0 ){
                    $extcj['beizhu'] = '系统赠送，充值满送金额';
                    $extcj['cjje'] = $order_info['hy_msje'];
                    $extcj['cjhje'] = $cjhje;
                    Db::name('caijin_list')->insert($extcj);
                }
                $cjhje += floatval($order_info['hy_zsje']);
                if( floatval($order_info['hy_zsje']) > 0 ){
                    $extcj['beizhu'] = '系统赠送，充值等级赠送金额';
                    $extcj['cjje'] = $order_info['hy_zsje'];
                    $extcj['cjhje'] = $cjhje;
                    Db::name('caijin_list')->insert($extcj);
                }
                $cjhje += floatval($order_info['method_money']);
                if( floatval($order_info['method_money']) > 0 ){
                    $extcj['beizhu'] = '系统赠送，充值方案赠送金额';
                    $extcj['cjje'] = $order_info['method_money'];
                    $extcj['cjhje'] = $cjhje;
                    Db::name('caijin_list')->insert($extcj);
                }

                $data = array('username' => $order_info['username'], 'test' => "您账户充值金额：{$order_info['je']}，赠送金额：{$fav_money}。已充值到账，请注意查收！", 'xx_time' => $ctime, 'ifdq' => 0);
                Db::name('xiaoxi')->data($data)->insert();
                Db::commit();
                return 'ok';
            } catch (\Exception $e) {
                Db::rollback();
                return 'error';
            }
        }
        return 'error';
    }

    /**
     * 跳转接口
     */
    public function hrefUrl()
    {
        $memberid = input('post.memberid', '');
        $orderid = input('post.orderid', '');
        $amount = input('post.amount', '');
        $datetime = input('post.datetime', '');
        $transaction_id = input('post.transaction_id', '');
        $returncode = input('post.returncode', '');
        $sign = input('post.sign', '');

        $data = array(
            'memberid' => $memberid,
            'orderid' => $orderid,
            'amount' => $amount,
            'datetime' => $datetime,
            'transaction_id' => $transaction_id,
            'returncode' => $returncode
        );
        ksort($data);
        reset($data);

        $key = $this->key;
        $md5str = $this->bulidSign($data);
        $sign_str = strtoupper(md5($md5str . 'key=' . $key));

        if ($sign_str == $sign && $returncode == '00') {
            $this->buildHtml("充值成功，{$amount} 元已到账");
        } else {
            $this->buildHtml("充值失败");
        }
    }
    public function hrefUrlThird()
    {
        $memberid = input('post.memberid', '');
        $orderid = input('post.orderid', '');
        $amount = input('post.amount', '');
        $datetime = input('post.datetime', '');
        $transaction_id = input('post.transaction_id', '');
        $returncode = input('post.returncode', '');
        $sign = input('post.sign', '');

        $data = array(
            'memberid' => $memberid,
            'orderid' => $orderid,
            'amount' => $amount,
            'datetime' => $datetime,
            'transaction_id' => $transaction_id,
            'returncode' => $returncode
        );
        ksort($data);
        reset($data);

        $key = $this->key;
        $md5str = $this->bulidSign($data);
        $sign_str = strtoupper(md5($md5str . 'key=' . $key));

        if ($sign_str == $sign && $returncode == '00') {
            $this->buildHtml("充值成功，{$amount} 元已到账",1);
        } else {
            $this->buildHtml("充值失败",1);
        }
    }

    /**
     * 生成签名
     */
    private function bulidSign($array)
    {
        $md5str = '';
        foreach ($array as $k => $v) {
            $md5str = $md5str . $k . '=' . $v . '&';
        }
        $md5sign = strtoupper(md5($md5str . 'key=' . $this->key));
        return $md5sign;
    }

    private function curl_post_https($url,$data){ // 模拟提交数据函数
        $curl = curl_init(); // 启动一个CURL会话
        curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // 从证书中检查SSL加密算法是否存在
        curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
        curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包
        curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
        curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
        $tmpInfo = curl_exec($curl); // 执行操作
        if (curl_errno($curl)) {
            echo 'Errno'.curl_error($curl);//捕抓异常
        }
        curl_close($curl); // 关闭CURL会话
        return $tmpInfo; // 返回数据，json格式
    }

    /**
     * POST
     */
    private function requestPost($pay_url, $post_data)
    {
        $post_string = http_build_query($post_data);
        $options = array(
            'http' => array(
                'method' => 'POST',
                'header' => 'Content-type:application/x-www-form-urlencoded',
                'content' => $post_string,
                'timeout' => 15 * 60 // 超时时间
            )
        );
        $context = stream_context_create($options);
        $result = file_get_contents($pay_url, false, $context);
        return $result;
    }
}
